<!--
@description: Vue原理
@author: ldb
@time: 2022-11-08 20:45:47
-->
<template></template>

<script lang="ts" setup>
// @ts-ignore
import {
  effect,
  reactive,
  computed,
  watch,
  shallowReactive,
  readonly,
  shallowReadonly,
  ref,
} from './reactive/reactive-core.js'
import { LocalStorageCache } from '@/utils/cache-util'
// 代理对象
/*const obj = {
  ok: true,
  text: 'ok',
  foo: true,
  bar: true,
  num: 0,
}

const proxy = new Proxy<any>(obj, {
  get(target, key: string) {
    // 获取时，跟踪
    track(target, key)
    return target[key]
  },
  set(target, key: string, value: any) {
    target[key] = value
    // 设置时，触发更新
    trigger(target, key)
    return true
  },
})*/
// 1、移除不必要的副作用
/*effect(() => {
  document.body.innerText = proxy.ok ? proxy.text : 'non'
})
setTimeout(() => {
  proxy.ok = false
}, 2000)*/

// 2、嵌套的effect
/*let temp1, temp2
effect(() => {
  console.log('effectFn1执行')
  effect(() => {
    console.log('effectFn2执行')
    temp2 = proxy.bar
  })
  temp1 = proxy.foo
})
// 2、当我们修改外层的副作用函数的时候，发现里面的副作用函数居然被执行了?
proxy.bar = false*/

// 3、避免无限递归循环
/*effect(() => {
  proxy.num = proxy.num + 1
})*/

// 4、可调度
/*effect(
  () => {
    console.log(proxy.foo)
  },
  {
    scheduler(fn: Function) {
      setTimeout(fn)
    },
  },
)
proxy.foo = false
console.log('the end')*/

/*const effectObj = effect(
  () => {
    console.log(proxy.num)
  },
  {
    scheduler(fn: Function) {
      jobQueue.add(fn)
      flushJob()
    },
    lazy: false,
  },
)*/
/*proxy.num++
proxy.num++*/
// 5、手动执行副作用函数
// effectObj()

// 6、computed
// const obj = reactive({ foo: 1, bar: 2 })
// const sumRes = computed(() => obj.foo + obj.bar)
// console.log(sumRes.value)
// todo 修改了居然没有触发
// obj.foo = 8
// console.log(sumRes.value)
// 7、computed的缺陷(effect嵌套时，外层的effect不会执行，需要我们手动触发)
/*effect(() => {
  // 在当前副作用中，读取计算属性
  console.log(sumRes.value)
  document.body.innerHTML = sumRes.value
})
obj.foo++*/

// 8、watch
/*const data = { foo: 1 }
const obj = reactive(data)*/
/*watch(obj, (oldV: any, newV: any) => {
  console.log(oldV, newV)
})
  obj.foo = 2*/
/*watch(
  () => obj.foo,
  (newV: any, oldV: any) => {
    console.log(newV)
    console.log(oldV)
  },
  {
    immediate: false,
  },
)*/
// obj.foo++
// 9、代理对象
/*effect(() => {
  console.log(obj.foo)
})
obj.foo = 1*/

/*const obj = {}
const proto = { bar: 1 }
const child = reactive(obj)
const parent = reactive(proto)
Object.setPrototypeOf(child, parent)
effect(() => {
  console.log(child.bar)
})
child.bar = 2*/

/*const obj = reactive({ foo: { bar: 1 } })
effect(() => {
  console.log(obj.foo.bar)
})
obj.foo.bar = 2*/

/*const val = { foo: { bar: 1 }, bar: 111 }
const obj = shallowReadonly(val)
effect(() => {
  console.log(obj.bar)
  console.log(obj.foo.bar)
})
obj.foo.bar = 222
// obj.bar = 2
console.log(obj.foo.bar)*/

// 10、代理数组
/*const arr = [1]
const obj = reactive(arr)
effect(() => {
  console.log(obj.push(2))
})
effect(() => {
  console.log(obj.push(3))
})*/

// 11、代理 Set 和 Map
/*const map = new Map()
const obj = reactive(map)
effect(() => {
  obj.get('key')
})
obj.set('key', 1)*/
/*const s = new Set([1, 2, 3])
const p = reactive(s)*/
// console.log(p.size)
// p.delete(1)
/*let val = ref(1)
effect(() => {
  console.log(val)
})
val.value = 5*/

// 渲染器
</script>

<style scoped lang="scss"></style>
